iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
Modern Web

你的第一本 AEO x GEO 教戰手冊系列 第 4

UA 會騙人:用 IP 與 ASN 撕下 AI 爬蟲的偽裝,實測那些冒名頂替的騙子

  • 分享至 

  • xImage
  •  

昨天我們拆解了 AI 流量的三種行為。今天我們要來摧毀一個更基礎的信任前提:你憑什麼相信門外那個自稱 GPTBot 的真的是他?

答案很殘酷:你根本不知道。log 裡那欄叫做 User-Agent 的東西,純粹是對方自己填寫的搭訕台詞。沒有簽章,沒有憑證,沒有任何人幫他背書:

curl -A "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.4; +https://openai.com/gptbot" \
  https://你自己的站/

這筆請求會大搖大擺走進你的伺服器,被大部分的報表軟體算成一次 OpenAI 的造訪,然後長在你「本週 AI 爬蟲」那張圖表的 OpenAI 柱狀圖上。從數據表面來看,他跟真正的 GPTBot 毫無破綻。因為那些分類器從頭到尾只看了他遞過來的名片。我們自己的分類器也是用正規表達式去比對 UA,字串對了就放行,廠商名稱直接抄註冊表。這中間根本沒有人停下來質問一句:「這個位址真的屬於這家公司嗎?」

今天我們要補上的,就是那段被草率跳過的信任查核:在對方的「片面宣稱」與「真實身分」之間,到底有什麼東西是可以當作鐵證的。

三條驗證線

Cloudflare 在他們「已驗證機器人」的文件裡,把查勤的方法濃縮成了一句話(官方原話):

「Honest self-identification : it declares who it is deterministically, through a cryptographic Web Bot Auth signature, a published IP list with a stable user-agent, or reverse DNS.」

簽章 (Web Bot Auth) 是未來最完美的解答,這我們留到系列後面單獨聊。今天先談現在就能用的兩招,外加一條側面打聽的線索。這裡有個底線:這三條線索絕對不能被偷懶攪和成一個總分。

線一:廠商公布的 IP 範圍

OpenAI、Anthropic、Perplexity、Google 都公開了自家爬蟲出沒的網段,通常是一份 JSON 檔案。在我們手上的爬蟲註冊表裡有 246 個條目,其中 46 個帶有官方 IP 清單的網址,涵蓋了 15 家公司。把清單抓下來,看看對方是不是從這個地址來的,聽起來很簡單對吧。

但如果你真的去翻那些檔案,你會發現三件官方絕對不會主動告訴你的殘酷現實(這是我在 2026-09-06 當天查勤抓檔的所見所聞):

一、新鮮度差很多,而且檔案自己會告訴你。 OpenAI 的 gptbot.json 裡有個 creationTime 欄位,數值停在 2025-10-30T11:00:00.000000,這已經是快十個月前的舊名單了。而 Anthropic 的 bots.json 則是 2026-08-18T23:56:36Z,不到三週前剛更新。同樣叫做「官方公布的 IP 清單」,一份是上個月的熱乎承諾,另一份根本是去年的歷史陳跡。

二、多數清單沒有 IPv6。 gptbot.json 裡那 21 個項目清一色全是 ipv4Prefix。Anthropic 的 26 個項目也全都是 IPv4。如果對方是從 IPv6 找上門的,這條線索直接作廢。這不是把對方判成騙子,是系統根本無從查證。如果你的網站開了 IPv6,而你的驗證管線沒有把這種情況老實標示為「未知」,那你就會系統性地冤枉一票 v6 流量。

三、顆粒度不一定是量身打造的。 OpenAI 乖乖把名單切成四份 (gptbot / chatgpt-user / searchbot / adsbot),對上 IP 你就知道門外站的是哪一個分身。但 Anthropic 給的卻是一份大鍋炒的合併清單,不分爬蟲種類,也沒有 UA token。這意味著命中清單只能證明「他確實是 Anthropic 的人」,卻無法證明「他是來抓資料的 ClaudeBot 還是代客跑腿的 Claude-User」。而這兩種身分在 robots.txt 裡的待遇是天壤之別的(這點明天會深聊)。

最要命的極限是:這些清單是會悄悄搬家的。所以當一個位址「不在清單裡」時,你唯一能推論的真相只有一個:

「在我們讀到的那份清單裡,找不到這個位址。」
這句話描述的是你手上的名單不夠新,而不是指控對方的來歷造假

這不是文青在咬文嚼字。我們自己曾經兩次從「自家探測器被擋」就武斷推論「客戶網站的爬蟲進不去」。兩次都大錯特錯。把自己的處境當成全世界的真相,是感情和技術裡最常犯的毛病。

Anthropic 自己在同一頁也留下了反向的警告(原話):

「Alternate methods like blocking IP address(es) from which Anthropic Bots operates may not work correctly or persistently guarantee an opt-out」

理由很簡單,你把他的 IP 封了,他連你門口的 robots.txt 都看不到。請把這句話刺在心上:IP 清單是拿來「相認」的,不是拿來「封殺」的。

線二:反向 DNS 正反解 (FCrDNS)

Google 的官方文件把動機寫得無比寫實(原話):

「This is useful if you're concerned that spammers or other troublemakers are accessing your site while claiming to be from Google.」

看見了嗎:「claiming to be from Google」 (宣稱自己是 Google)。這是整篇文章的靈魂,而且是廠商自己承認的。

查勤的步驟有三段:

  1. 對來源 IP 做 PTR 反解,揪出一個主機名稱。
  2. 這個名稱必須掛在廠商公開宣告的網域底下(例如 googlebot.com)。
  3. 把這個名稱重新正解回去,必須能指回原本那個 IP。

這第三步才是整個查核機制站得住腳的關鍵。任何人都可以把自己的 IP 反解指向 crawl-foo.googlebot.com,因為反解是由位址持有者自己設定的。但全世界只有 Google 能讓那個網址正解回那個位址,因為正解的權力握在網域持有者手裡。兩邊的說法完全吻合,這段關係才算過關。

比對主機名稱的時候有個必踩的陷阱:請嚴格檢查網域邊界evil-googlebot.com 不是 googlebot.comx.googlebot.com.attacker.net 更是來騙人的:

// 這是對的防守
h === domain || h.endsWith(`.${domain}`)
// 這是錯的,而且它會默默放任別人劈腿
h.includes(domain)

FCrDNS 最大的悲哀在於它的覆蓋率。這招要求廠商願意公開 PTR 網域,但願意這麼坦蕩的少之又少。我們的系統裡只敢寫死兩家:google (包含 googlebot.com / google.com / googleusercontent.com) 與 microsoft (search.msn.com)。一份 IP 清單不等於一份 PTR 網域宣告,要新增一家查核對象,你就得親自去讀那家的驗證頁面,絕對不能從 IP 清單去瞎猜。

我在 2026-09-06 那天把 OpenAI、Anthropic、Perplexity、Google 四家的官方爬蟲文件從頭到尾翻了一遍。結果讓人心寒:四家都公開了 IP 清單,但只有 Google 給了反向 DNS 驗證的教學,也只有 Google 坦白承認「有人會冒充我」。三家 AI 廠商的文件裡完全沒有驗證章節,沒有任何一家願意寫下「我們的 UA 可以被偽造,請務必驗證 IP」這種提醒。

這個沉默本身就震耳欲聾:你手邊最完整、最教你怎麼保護自己的「防詐騙指南」,居然是來自一家根本不做生成式爬蟲的老牌搜尋引擎。

線三:IP 轉 ASN 歸屬

ASN 是 IP 網段在網路世界裡的戶籍地。查一個位址的 ASN,你就會知道他到底住在哪裡:是高大上的 AWS、GCP 公有雲,廉價的機房代管,還是普通的家庭寬頻 ISP。

ASN 只是旁敲側擊的佐證,不是一槌定音的判決。它沒辦法回答「這到底是不是 OpenAI」,因為 AI 爬蟲幾乎都租用公有雲,一個 AWS 的位址今天可能被 AI 公司包下,下週就換成某個不知名的新創。但它非常擅長戳破另一種謊言:這波流量的氣質到底像不像活人? 一波自稱是正常瀏覽器的流量,如果兩百多個 IP 全都擠在冰冷的機房和跳板網段,住宅區 ISP 的數字掛零,那這絕對不是「一群熱情的使用者」。這種殘酷的真相 ASN 說得出口,光看 IP 卻是看不出來的。

自建 ASN 查表:免費,而且比你想的輕巧

很多人以為查 IP 的 ASN 必須花錢買 API 或是註冊一堆帳號。根本不用。iptoasn.com 提供了一份 ip2asn-combined.tsv.gz,授權條款清清楚楚寫著 「Licensed under Public Domain (PDDL v1.0)」。這是公有領域的宣告,不需要帳號,不用標示出處,沒有使用範圍限制,拿去商用也毫無問題。發布方甚至明講了,讓你下載離線快照就是他們預期的玩法。資料來源是 RouteViews,上面標示著 「Updated hourly.」 格式是純粹的五欄 TSV (range_start / range_end / AS_number / country_code / AS_description),壓縮後只有 9 MB。

我實際把它倒進 Postgres 資料庫裡秤過斤兩:

檔案內總列數 717,360
有路由 (AS 不等於 0) 且實際保留 578,010 (其中 IPv4 有 456,233,IPv6 有 121,777)
無路由被丟棄 139,350
格式錯誤 0
相異的 AS 名稱 86,886
範圍表落地佔用 52 MB (包含主鍵)
名稱表落地佔用 7 MB
單次查詢效能 主鍵反向索引掃描,動用 7 個 buffer,只需 0.14 ms

你只要付出 59 MB 的硬碟空間,就能換來一套完整、不需要看任何人臉色的離線 ASN 查詢能力。不用依賴外部服務,不用管速率限制,也不用煩惱帳號過期。這門檻低得遠超乎大部分人的想像。

這裡我刻意做了一個取捨:解析時我把國別欄位直接刪了。這不是用來抓地理位置的工具,留著這個欄位,遲早會有人拿它去編造一些 ASN 根本無力背書的謊言。

實測一:自稱 Googlebot 的位址,83 比 1

在一個 30 天的觀測期內,我們抓出一批自稱是 Googlebot、但 IP 卻落在 Google 公布範圍之外的訪客。這群騙子的相異 IP 數量,是乖乖待在範圍內的真 Googlebot 的 83 倍

83 比 1 這個數字本身不能定讞,畢竟「不在清單裡」只代表我們的名單沒更新。所以我做了第二次查核:從範圍外隨機抽 20 個位址去跑 FCrDNS 反解,通過數是 0 個。接著從範圍內抽 20 個當作對照組,通過數是 20 個

對照組才是這場驗證的靈魂。如果沒有那 20 個滿分,你大可以把「範圍外 0/20」解釋成是我們的解析器壞了。但有了 20/20 的對照,殘酷的真相只剩下一個:那些人全都是假冒的。

換句話說,當一個客戶看著報表上寫著「Googlebot 造訪 N 次」,他看到的絕大部分根本不是 Google。全是一群披著外衣的騙子。

實測二:我們自己的站,一分鐘內,138 筆

第二個例子發生在 arrivl.ai 自己家裡,所以細節我可以毫無保留地攤開來。

2026-09-01 這天,我們自家的網域湧入了 138 筆被歸類到「其他機器人」的奇怪請求:

  • 100% 都用同一個 UAHeadlessChrome/151
  • 全都來自同一個單一來源位址34.46.170.181,這是一個 GCP 的雲端位址。
  • 全部擠在 17:20 UTC 這短短的一分鐘之內爆發
  • 路徑非常明確:從 //integrations/*/signup/login

隔天,同一個位址對我們監測的另一個網站幹了完全一樣的事,但那一輪他更心機,把 **referer 偽造成 [https://www.google.com/](https://www.google.com/)**

這個案例的價值在於,他不是來假冒 GPTBot 的。這是另一種更惡劣的行徑:他連裝成大廠都懶,直接套了一件無頭瀏覽器的風衣,再隨手捏造一個搜尋引擎的來路,妄想把自己裝扮成自然的過客。老實說,UA 寫著 HeadlessChrome 已經是他最誠實的瞬間了。如果他有心騙到底,換成一般 Chrome 的字串根本不需要成本,那樣他就會直接混進「人類訪客」的報表裡。

判讀這種行為的重點只有一個:行為輪廓是最便宜也最真實的訊號。 一個位址、一分鐘內、138 筆請求、路徑精準覆蓋整個註冊漏斗,光看這四點,你根本不需要去查什麼外部資料。一次真正來自 Google 搜尋的點擊絕對不會長這副德性,所以那個 referer 絕對是假的。查 IP 與 ASN 是用來確認你早就看穿的謊言,而不是用來取代你自己的雙眼。

碰撞檢查:一種接近鐵證的判定

前面三條線都有一種「查不到不代表他就是假的」的無奈極限。那有沒有那種一翻兩瞪眼、接近鐵證的判決方式?有,就是查跨廠商 UA 碰撞

同一個 IP 位址,在同一天之內,居然自稱是兩家不同公司的伺服器端爬蟲。這就是毫無懸念的冒名劈腿。

這條規則可以踩得很死。因為兩家水火不容的競爭公司,絕對不可能共用同一台機器來發送爬蟲。GPTBot 跟 ClaudeBot 從同一個位址走出來,這在物理上就沒有任何清白的解釋。

但這裡有一個必須寫死的例外,不加上這條,你絕對會濫殺無辜:

從使用者個人裝置端發出的字串,沒有投票權。

像是連結預覽 (link preview) 抓取、手機 App 內建的 AI 客戶端,這些都是跑在使用者自己的裝置上。在同一個 NAT 出口、同一道企業防火牆背後、或是同一個電信業者的 CGNAT 池子裡,完全有可能合理地擠滿了各家廠商的字串。如果你把這些也算進劈腿判定裡,你就會把一整棟無辜的辦公大樓判成冒名現場。所以,只有那些「伺服器端主動爬取」的 UA 才有資格被拿來當作對質的證據。

這招在實務上殺傷力極強。我們在日誌鑑識時,把「跨廠商碰撞」加上「公布 IP 範圍比對」綁在一起用。在台灣某個電商網站上,自稱 AI 爬蟲的請求有極高比例被我們當場判定為冒名。這雖然只是單一網站的縮影,不能代表全球的普遍比例,但這足以證明,這組訊號真的能像照妖鏡一樣,把隱藏在 log 裡的騙子一個一個揪出來。

三值判定:你對數據誠實的最後底線

走到這一步,誘惑其實很大。你一定很想把這三條線索加權平均,揉成一個 0 到 100 的「可信度分數」,低於某個及格線就無腦標記成「假流量」。

千萬不要這麼做。 我們的判定表嚴格遵守三個值,而且在資料庫結構上直接鎖死,絕不給第四個曖昧的空間:

真實含義 什麼情況會落到這個下場
verified 查了,而且對上了 位址在當天的官方清單內;FCrDNS 正反解雙雙通過檢驗。
unconfirmed 查了,但沒對上 位址不在我們手邊的那份清單裡;PTR 存在但查出來不是他們家的。
unknown 根本沒查成 當天清單抓取失敗;DNS 逾時;或者這隻 bot 根本沒有提供任何驗證管道。

有四件事你必須死死守住:

一、unconfirmed 絕對不等於「假」。 我們的資料表裡有一道 CHECK 約束,直接把 'fake' 這個字串給拒於門外。因為我知道,總有一天會有人想偷懶,把所有 unconfirmed 的人全部打成 fake。合理落進 unconfirmed 的情況至少有兩種:一種是真的從住宅區 ISP 走出來的 ChatGPT-User (因為使用者觸發的即時抓取,常常不在官方公布的爬蟲網段裡);另一種是廠商在流量已經灌進來之後,才慢吞吞補進清單的新網段。

二、抓取失敗必須歸在 unknown,不是 unconfirmed 這條線特別容易在寫程式時搞砸,因為在邏輯上這兩者看起來都是「沒對上」,但在感情語意上卻是天壤之別。如果廠商的 JSON 伺服器回了 500 錯誤,那天所有的位址都應該是 unknown。如果你硬寫成 unconfirmed,你的報表上就會憑空長出一根巨大的「冒名尖峰」,而殘酷的真相只是你自家的抓取器當機了。DNS 也是同樣的道理,解析器逾時叫 unknown,「PTR 查得到但不是他家的」才叫 unconfirmed。

三、過期的快照只能用來證明昨天的清白。 判定必須死死綁定當天的那份快照。當今天抓取失敗時,你絕對不可以偷偷退回去拿昨天的清單來擋槍。

四、三條線必須並列,永遠不要試圖把它們融為一體。 分歧本身就是極具價值的情報。我們曾經看過 PerplexityBot 在某個時間段內的 794 次請求裡,通過 Cloudflare 驗證的次數是 0 次 (但同時流量表現一切正常)。我們也看過 Bytespider 被 Cloudflare 驗證為「搜尋引擎爬蟲」,這跟我們自己歸類的屬性完全衝突。如果你把這些線索平均成一個分數,你正好親手銷毀了這些分歧所夾帶的珍貴線索。

還有一個很容易被誤讀的 NULL 空值:「沒有驗證結果」同時代表著「驗證方看到了但他懶得驗」以及「我們根本沒去問」。這絕對不能當成 0 分來處理。實測上,流量前 30 名的專案裡,只有 7 個擁有 Cloudflare 邊緣判定的資料。如果你直接去算非空值的比例,報表就會對另外 23 個專案顯示「Cloudflare 驗證通過率 0%」。這根本是把「缺乏證據」扭曲成「證據確鑿的背叛」。

最後一條鐵律:單一的判定結果,永遠不足以觸發警報。 當你準備開口說出「你的網站有冒名問題」之前,你手邊至少要有足夠的樣本 (我們的門檻是這隻 bot 至少有 20 次被檢查過的請求) 以及足夠高的佔比。而且分母必須誠實地標示為「我們有能力檢查的請求總數」。那些打從一開始就沒有提供驗證管道的 bot,從來就不該出現在分母裡。同理,這種驗證機制應該跑在批次、離線、只讀的環境裡,絕對不該擋在收資料的門口。因為一旦判錯了方向,你就會永久刪除一筆真實的爬蟲拜訪紀錄,那是救不回來的。

小結

  • User-Agent 只是對方的片面宣稱,絕不是真實身分。 隨便敲一行 curl,誰都能假裝成大廠的爬蟲來敲門。
  • 三條查勤底線:官方 IP 範圍 (覆蓋了 AI 廠商但名單會漂移,而且多半沒有 IPv6)、FCrDNS 反解 (方法最嚴謹,但願意配合的廠商極少)、IP 轉 ASN (只是佐證,不是最終判決)。
  • 自建 ASN 查表免費又輕巧:拿公有領域的資料集,578,010 條有效網段,落地只要 59 MB,單次查詢 0.14 ms,根本不需要看別人的臉色。
  • 跨廠商 UA 碰撞最接近劈腿的鐵證,但記得把使用者個人裝置的字串排除在外,免得濫殺無辜。
  • 三值判定是你對數據誠實的最後底線unconfirmed 不是假流量,抓取失敗就是 unknown。把真實的流量隨便貼上詐騙標籤,是做分析最糟糕的墮落。

明天我們要來談另一個關於「宣稱」的謊言,但方向剛好反過來。robots.txt 是我們對爬蟲做出的宣稱。當你冷酷地寫下 Disallow 之後,到底有誰會真的理你?這件事,我們教你怎麼自己量。


本文是「你的第一本 AEO x GEO 教戰手冊」系列第 4 天。系列實測與數據由 arrivl arrivl 整理 (Growth Analytics for the Agentic Web)。


上一篇
三種 AI 流量:訓練爬取、即時檢索、AI 導流,他們的行為完全不同
下一篇
robots.txt 的 AI 條目:你立下的規矩,到底有誰在乎?教你親自驗證他們的忠誠度
系列文
你的第一本 AEO x GEO 教戰手冊7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言